<?php
/**
 * @brief Klasa encyjna Group
 * 
 * Obiekty tej klasy są reprezentacją grupy pod-ofert. 
 * 
 */
class Application_Model_Group
{
    //trybuty
    protected $Group_id; /*!< Identyfikator grupy. */
    protected $multipler; /*!< Mnoznik */
    protected $isMandatory; /*!< Atrybut opcjonalnosci */
    protected $MarketEntity_id; /*!< Wlasciciel grupy */
    protected $headOffer_id; /*!< Identyfikator oferty nadrzednej */
    
    //obekty pochodne
    protected $offers = array(); /*!< Zagregowane w grupe oferty */
    
    //klasy mapujące
    protected $_groupMapper; /*!< Mapper grupy */
    protected $_offerMapper; /*!< Mapper ofert. */
    
    /**
    * @brief Konstruktor
    * 
    */
    public function __construct(array $options = null) {
        if (is_array($options)) {
            $this->setOptions($options);
        }
        $this->_groupMapper = new Application_Model_GroupMapper();
        $this->_offerMapper = new Application_Model_OfferMapper();
    }

   /**
    * @brief Metoda ustawiajaca parametry grupy
    * 
    * Przyjmuje na wejsciu tablce z atrbutami i wywołuje settery
    */
    public function setOptions(array $options) {

        $methods = get_class_methods($this);

        foreach ($options as $key => $value) {

            $method = 'set' . ucfirst($key);

            if (in_array($method, $methods)) {

                $this->$method($value);
            }
        }
        return $this;
    }

   /**
    * @brief Metoda zwracająca id ofert nadrzednej
    * 
    * 
    */
    public function getHeadOffer_id() {
        return $this->headOffer_id;
    }
    
   /**
    * @brief Metoda zwracająca id ofert nadrzednej
    * 
    * 
    */
    public function setHeadOffer_id($headOffer_id) {
        $this->headOffer_id = $headOffer_id;
    }

   /**
    * @brief Metoda dodajca nowa oferte do grupy
    * 
    * 
    */
    public function addOffer($offer){
        $this->offers[] = $offer;
    }
    
   /**
    * @brief Metoda zwracająca mnoznik
    * 
    * 
    */
    public function getMultipler() {
        return $this->multipler;
    }

   /**
    * @brief Metoda zwracajaca mnoznik
    * 
    * 
    */
    public function setMultipler($multipler) {
        $this->multipler = $multipler;
    }

   /**
    * @brief Metoda zwracająca nazwe wlasciciela grupy
    * 
    * 
    */
    public function getMarketEntity_id() {
        return $this->MarketEntity_id;
    }

   /**
    * @brief Metoda do ustawiania nazwy wlasciciela grupy
    * 
    * 
    */
    public function setMarketEntity_id($MarketEntity_id) {
        $this->MarketEntity_id = $MarketEntity_id;
    }
    
   /**
    * @brief Metoda zwracająca atrybut opcjonalnosci grupy
    * 
    * 
    */
    public function getIsMandatory() {
        return $this->isMandatory;
    }

   /**
    * @brief Metoda do ustawiania atrybutu opcjonalnosci grupy
    * 
    * 
    */
    public function setIsMandatory($isMandatory) {
        $this->isMandatory = $isMandatory;
    }
      
   /**
    * @brief Metoda zwracająca identyfikator grupy
    * 
    * 
    */
    public function getGroup_id() {
        return $this->Group_id;
    }

    public function setGroup_id($Group_id) {
        $this->Group_id = $Group_id;
    }

    /**
    * @brief Metoda zwracająca liste agregowanych w overcie grup
    * 
    * 
    */
    public function getOffers() {
        if(empty($this->offers)) {
            $this->setOffers();
        }
        return $this->offers;
    }
   
    /**
    * @brief Metoda wyszukujaca liste agregowanych w overcie grup
    * 
    * Za pomoca mappera ofert, są one wyciągane z bazy danych
    */
    public function setOffers() {
        $groupId = $this->getGroup_id();
        $offerMapper = new Application_Model_OfferMapper();
        $this->offers = $offerMapper->fetchOfferByGroup($groupId);
    }
    
   /**
    * @brief Metoda serializaujca grupe do M3XML
    * 
    * Tworzone są w niej wszystkie rodzaje wirtualnych ofert posredniczacych 
    * i powiazne zn nimi wirtualne towary grupy.
    */
    public function toXML($info, $offerId ,$maxVolume) {
        $visitedGroups = $info['groups'];
        $postfix = false;
        if(in_array($this->Group_id, $visitedGroups)) {
           $postfix = true; 
        }
        $volume = $this->multipler * $maxVolume;
        
        $msg = $this->getOfferXML($volume, $offerId, true, $postfix);
        if(!$this->isMandatory){
            $msg .= $this->getOfferXML($volume, $offerId, false, $postfix);
        }
        $info['offers'] .= $msg;
        if(!in_array($this->Group_id, $visitedGroups)) {
           $info['commodities'] .= $this->getCommodityXML();
           $info['groups'][] = $this->Group_id;
           $offers = $this->getOffers();
           foreach($offers as $offer){
               $info = $offer->toXML($info, $volume);
           }
        }
        return $info;
    }
    
   /**
    * @brief Metoda mapujaca grupe do M3XML
    * 
    * Uwzgledniany jest fakt ze oferty moga nalezec do kliku ofert.
    * za pomoca tej metody tworzone sa oba rodzaje wirtualnych ofert
    * posredniczacych
    */
    private function getOfferXML($volume, $offerId ,$mandatory, $postfix) {
        if($mandatory) {
            $id = 'og'.$this->getGroup_id();
        } else {
            $id = 'osg'.$this->getGroup_id();
        }
        if ($postfix) {
            $id .= 'o'.$offerId;
        }
        $xml = '
                <m3:Offer id="'.$id.'" offeredPrice="0">
                    <m3:description>Virtual Offer form group subbmited by consumer '.$this->getMarketEntity_id().'</m3:description>
                    <m3:offeredBy ref="'.$this->getMarketEntity_id().'" />
                    <m3:volumeRange maxValue="'.$volume.'" minValue="0" />
                    ';
        if($mandatory) {
            $xml.= '<m3:BundledOffer>
                        ';
            $xml .='<m3:offeredCommodity ref="vcg'.$this->Group_id.
                        '" shareFactor="'.$this->multipler.'" />
                        ';
        } else {
            $xml .= '<m3:ElementaryOffer>
                        ';
        }
        $xml .='<m3:offeredCommodity ref="pvcO'.$offerId.
                        'G'.$this->Group_id.'" shareFactor="-1" />
                    ';
        if($mandatory) {
            $xml .= '</m3:BundledOffer>
                ';
        } else {
            $xml .= '</m3:ElementaryOffer>
                ';
        }
        $xml .= '</m3:Offer>
                ';
        return $xml;
    }
    
   /**
    * @brief Metoda generujaca zapis wirtualnego towaru grupy w M3XML
    * 
    * 
    */
    private function getCommodityXML() {
        $msg = '
               <m3:Commodity dref="virtual" id="vcg'.$this->Group_id.'">
                 <m3:description>Virtual commodity for group '
                        .$this->Group_id.'</m3:description>
                 ';
         $msg .='</m3:Commodity>
             ';
         return $msg;
    }
    
}

